package com.cctc.juc.demo.Bitc;
/**
 * 【Java 线程间通信】
 * 1. 概述：线程间通信（ITC, Inter-Thread Communication）是指在多线程编程中，多个线程之间通过共享内存或其他机制进行信息传递、同步和协作的过程。
 * 2. 关键点：
 * 1）信息传递；
 * 2）线程同步；
 * 3）多线程任务调度。
 * 3. 实现方式：
 * 1）使用共享变量。该方式是最简单，也是最常见的线程间通信方式，多个线程可以通过读写共享变量来进行通信。在 Java 中，可以：
 * - 使用 volatile 关键字来保证共享变量的内存可见性和指令有序性，
 * - 然后基于 cas 原子操作实现共享变量的互斥访问，保证线程安全；
 * - 或者基于 final 关键字创建 “不可变” 对象，在没有任何同步机制的情况下进行共享，降低对该对象进行并发访问时的同步化开销；
 * - 最后，还可以使用 synchronized 内置锁、JUC 显式锁等同步临界区代码块，达到同样的目的。
 * 2）基于线程阻塞与唤醒机制。线程阻塞与唤醒机制也是实现线程间通信的经典方式。在 Java 中，
 * - 可以使用 Thread.join() 方法，实现自我阻塞，等待子线程执行完成后被唤醒，再继续向下执行，以控制线程的执行顺序；
 * - 还可以使用 Object 类的 wait() 和 notify[All]() 方法，在 synchronized 内置锁控制的同步代码块中实现线程的阻塞与唤醒；
 * - 也可以使用 JUC 显式锁提供的 LockSupport 类中的 park() 和 unpark() 方法，在任意地方（不需要显式获得锁）更加方便、灵活的实现线程的阻塞与唤醒。
 * 3）使用条件变量。多个线程也可以通过条件变量来进行通信，一个线程可以在某个条件变量上进行等待，当条件被满足时，另一个线程可以通过此条件变量唤醒等待的线程继续向下执行。在 Java 中，可以在 Lock 锁对象的上创建一个或多个 Condition 条件变量，然后通过 await()、signal[All]() 方法实现线程在某个条件变量下的等待与唤醒。
 * 4）使用阻塞队列。多个线程可以通过阻塞队列来进行通信，生产者线程往阻塞队列中放入数据，消费者线程从同一个阻塞队列中取出数据，从而实现线程间的信息传递。
 * 5）使用管道。与阻塞队列类似，多个线程也可以通过管道来进行通信，一个线程可以往管道中写入数据，另一个线程从管道中读取数据，从而实现线程间的信息传递。
 * - 管道是 Linux 内核提供的一种进程间通信方式，它主要用于父子线程或者关联性比较强的线程间的数据传递，通过作为管道流来使用。
 * 6）使用信号量、倒数闩 / 闭锁、循环屏障、移相器等 JUC 高级同步组件。例如：
 * - Semaphore 信号量：Semaphore 是 JUC 并发包中的一个高级同步组件，其功能相当于一个许可管理器，每个时刻只能允许获取固定数量许可证的线程并发执行，经常用来限制并发执行线程的数量，例如限流等。
 * - CountDownLatch 倒数闩 / 闭锁：CountDownLatch 也是 JUC并发包中的一个高级同步组件，其功能相当于一个倒数计数器，可以实现线程间等待。CountDownLatch 内部维护了一个计数器，主线程调用 await() 方法，进行自我阻塞，每个任务线程线程执行完成后，调用 countDown() 方法，将计数器的值减 1，当所有任务线程执行结束后，计数器值变为 0，主线程被唤醒，继续向下执行。
 * - CyclicBarrier 循环屏障：CyclicBarrier 也是 JUC 并发包中的一个高级同步组件，其功能相当于一个屏障点，通过它可以实现多个任务线程之间相互等待，只有当每个任务线程都准备就绪后，才能继续执行各自后续的操作。
 * - Phaser 移相器：Phaser 也是 JUC 并发包中的一个高级同步组件，它可以将任务线程的运行分为多个阶段，先到达前一阶段（phase 0）的任务线程需要自我等待（await），直到所有任务线程全部到达后再各自前往（advance）下一个阶段（phase 1），依次类推，直到终点。
 * 7）Future + Callable 异步通信。Future 和 Callable 是 Java 中实现线程间异步通信的一种方式。Callable 是一个接口，代表一个可以返回结果的任务，而 Future
 * 也是一个接口，代表着一个 Callable 任务的执行结果；首先将 Callable 任务提交到线程池中进行执行，线程池会返回一个 Future 对象，然后通过它获取 Callable 任务的执行结果，通过这种方式可以实现线程间的任务分配、执行和结果获取。
 * 以上是一些常见的 Java 线程间通信的方法，我们可以根据具体的需求和场景，选择适合的方式实现线程间的通信。
 * 4. 常见场景：
 * 1）生产者-消费者问题；
 * 2）读者-写者问题；
 * 3）多线程任务调度问题。
 * ... ...
 */